package com.tianyuan.lims.dms.controller.exam.service;

import com.alibaba.fastjson.JSON;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.tianyuan.lims.dms.controller.exam.entity.GeneratePaperRequest;
import com.tianyuan.lims.dms.controller.exam.entity.KnowledgeConfig;
import com.tianyuan.lims.dms.controller.exam.entity.PaperGenerateResult;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ExamRecordService {

    /**
     * 生成试卷
     */
    public PaperGenerateResult generatePaper(GeneratePaperRequest request) {
        PaperGenerateResult result = new PaperGenerateResult();

        // 1. 根据知识点权重分配题目数量
        Map<Long, Integer> questionCountByKnowledge = allocateQuestions(request);

        // 2. 从题库中随机抽取题目
        Map<String, List<Long>> questionIds = new HashMap<>();

        // 根据题型生成题目
        switch (request.getQuestionType()) {
            case "single":
                // 生成单选题
                generateSingleChoiceQuestions(questionCountByKnowledge, questionIds, request.getQuestionCount());
                break;
            case "multiple":
                // 生成多选题（暂不支持）
                break;
            case "judge":
                // 生成判断题（暂不支持）
                break;
            default:
                // 默认生成单选题
                generateSingleChoiceQuestions(questionCountByKnowledge, questionIds, request.getQuestionCount());
                break;
        }

        // 3. 构建返回结果
        result.setQuestionData(buildQuestionData(questionIds));
        return result;
    }

    /**
     * 根据知识点权重分配题目数量
     */
    private Map<Long, Integer> allocateQuestions(GeneratePaperRequest request) {
        Map<Long, Integer> questionCountMap = new HashMap<>();
        int totalQuestions = request.getQuestionCount();
        int allocatedQuestions = 0;

        // 第一轮分配：按权重计算理论数量
        for (KnowledgeConfig config : request.getKnowledgeConfig()) {
            double theoreticalCount = (config.getWeight() / 100.0) * totalQuestions;
            int count = (int) Math.floor(theoreticalCount); // 向下取整
            questionCountMap.put(config.getId(), count);
            allocatedQuestions += count;
        }

        // 第二轮分配：处理剩余题目（按小数部分排序分配）
        int remainingQuestions = totalQuestions - allocatedQuestions;
        if (remainingQuestions > 0) {
            // 按小数部分降序排序
            List<KnowledgeConfig> sortedConfigs = request.getKnowledgeConfig().stream()
                    .sorted((c1, c2) -> {
                        double decimal1 = (c1.getWeight() / 100.0 * totalQuestions) % 1;
                        double decimal2 = (c2.getWeight() / 100.0 * totalQuestions) % 1;
                        return Double.compare(decimal2, decimal1);
                    })
                    .collect(Collectors.toList());

            // 分配剩余题目
            for (int i = 0; i < remainingQuestions && i < sortedConfigs.size(); i++) {
                KnowledgeConfig config = sortedConfigs.get(i);
                questionCountMap.put(config.getId(), questionCountMap.get(config.getId()) + 1);
            }
        }

        return questionCountMap;
    }

    /**
     * 生成单选题
     */
    private void generateSingleChoiceQuestions(Map<Long, Integer> questionCountMap,
                                               Map<String, List<Long>> questionIds,
                                               int totalQuestions) {
        List<Long> singleIds = new ArrayList<>();

        for (Map.Entry<Long, Integer> entry : questionCountMap.entrySet()) {
            Long knowledgeId = entry.getKey();
            Integer count = entry.getValue();

            if (count > 0) {
                // 从题库中随机获取指定数量的单选题
                List<Record> questions = selectRandomQuestionsByKnowledge(knowledgeId, "1", count);

                for (Record question : questions) {
                    singleIds.add(question.getLong("id"));
                }
            }
        }

        // 如果实际题目数量不足，补充随机题目
        if (singleIds.size() < totalQuestions) {
            int remaining = totalQuestions - singleIds.size();
            List<Record> additionalQuestions = selectRandomQuestions("1", remaining);

            for (Record question : additionalQuestions) {
                singleIds.add(question.getLong("id"));
            }
        }

        questionIds.put("singleIds", singleIds);
    }

    /**
     * 根据知识点随机获取题目
     */
    private List<Record> selectRandomQuestionsByKnowledge(Long knowledgeId, String questionType, Integer count) {
            String sql = "SELECT q.id, q.content, c.id as knowledge_id, c.name as knowledge_name " +
                    "FROM lims_exam_question q " +
                    "LEFT JOIN lims_category c ON q.symbol = c.id " +
                    "WHERE c.id = ? and q.type = ? AND q.check_flag = 1 " +
                    "ORDER BY RAND() LIMIT ?";
//        return Db.find(sql, questionType, count);
            return Db.find(sql, knowledgeId, questionType, count);
    }



    /**
     * 随机获取题目（不指定知识点）
     */
//    private List<Record> selectRandomQuestions(String questionType, Integer count) {
//        String sql = "SELECT id, content, knowledge_id, knowledge_name " +
//                "FROM lims_exam_question " +
//                "WHERE question_type = ? AND status = 1 " +
//                "ORDER BY RAND() LIMIT ?";
//        return Db.find(sql, questionType, count);
//    }


    private List<Record> selectRandomQuestions(String questionType, Integer count) {
        String sql = "SELECT q.id, q.content, c.id as knowledge_id, c.name as knowledge_name " +
                "FROM lims_exam_question q " +
                "LEFT JOIN lims_category c ON q.symbol = c.id " +
                "WHERE q.type = ? AND q.check_flag = 1 " +
                "ORDER BY RAND() LIMIT ?";
        return Db.find(sql, questionType, count);
    }



    /**
     * 构建题目数据结构
     */
    private Map<String, Object> buildQuestionData(Map<String, List<Long>> questionIds) {
        Map<String, Object> questionData = new HashMap<>();

        // 单选题
        questionData.put("singleIds", questionIds.getOrDefault("singleIds", new ArrayList<>()));
        questionData.put("singleexamAnswers", new ArrayList<>());

        // 多选题（暂为空）
        questionData.put("multipleIds", new ArrayList<>());
        questionData.put("multipleexamAnswers", new ArrayList<>());

        // 判断题（暂为空）
        questionData.put("judgeIds", new ArrayList<>());
        questionData.put("judgeexamAnswers", new ArrayList<>());

        // 问答题（暂为空）
        questionData.put("answerIds", new ArrayList<>());
        questionData.put("answerexamAnswers", new ArrayList<>());

        // 计算题（暂为空）
        questionData.put("calcIds", new ArrayList<>());
        questionData.put("calcexamAnswers", new ArrayList<>());

        // 综合题（暂为空）
        questionData.put("volumeupIds", new ArrayList<>());
        questionData.put("volumeupexamAnswers", new ArrayList<>());

        return questionData;
    }

    /**
     * 保存试卷
     */
    public Record savePaper(Map<String, Object> saveData) {
        Record record = new Record();

        // 设置基本信息
        record.set("user_id", saveData.get("user_id"));
        record.set("bank_id", saveData.get("bank_id"));
        record.set("seconds", saveData.get("seconds"));
        record.set("score", saveData.get("score"));
        record.set("create_time", new Date());

        // 设置扩展信息（知识点配置）
        record.set("ext_json", saveData.get("ext_json"));

        // 设置题目数据
        Map<String, Object> questiondata = (Map<String, Object>) saveData.get("questiondata");
        record.set("questiondata", JSON.toJSONString(questiondata));

        // 设置作答记录
        record.set("result", saveData.get("result"));

        // 设置正确率字段（初始为0）
        record.set("rate1", 0);
        record.set("rate2", 0);
        record.set("rate3", 0);
        record.set("rate4", 0);
        record.set("rate5", 0);
        record.set("rate6", 0);
        record.set("rate7", 0);
        record.set("rate8", 0);

        // 保存到数据库
        Db.save("lims_exam_record", record);

        return record;
    }

    /**
     * 根据ID获取试卷记录
     */
    public Record getExamRecordById(Long id) {
        return Db.findById("lims_exam_record", id);
    }

    /**
     * 更新试卷记录
     */
    public boolean updateExamRecord(Record record) {
        return Db.update("lims_exam_record", record);
    }

    /**
     * 删除试卷记录
     */
    public boolean deleteExamRecord(Long id) {
        return Db.deleteById("lims_exam_record", id);
    }

    /**
     * 获取用户的所有试卷记录
     */
    public List<Record> getExamRecordsByUserId(Long userId) {
        String sql = "SELECT * FROM lims_exam_record WHERE user_id = ? ORDER BY create_time DESC";
        return Db.find(sql, userId);
    }

    /**
     * 获取题库的所有试卷记录
     */
    public List<Record> getExamRecordsByBankId(Long bankId) {
        String sql = "SELECT * FROM lims_exam_record WHERE bank_id = ? ORDER BY create_time DESC";
        return Db.find(sql, bankId);
    }







    /**
     * 获取用户的考试记录列表
     */
    public List<Record> getUserExamRecords(Long userId) {
        String sql = "SELECT er.*, " +
                "CASE WHEN er.score IS NULL AND er.seconds IS NULL THEN '进行中' " +
                "WHEN er.score IS NOT NULL THEN '已完成' " +
                "ELSE '未知' END as exam_status " +
                "FROM lims_exam_record er " +
                "WHERE er.user_id = ? " +
                "ORDER BY er.create_time DESC";

        return Db.find(sql, userId);
    }

    /**
     * 获取未完成的考试记录
     */
    public Record getUnfinishedExam(Long userId, Integer bankId) {
        String sql = "SELECT * FROM lims_exam_record " +
                "WHERE user_id = ? AND bank_id = ? " +
                "AND score IS NULL AND seconds IS NULL " +
                "ORDER BY create_time DESC LIMIT 1";

        return Db.findFirst(sql, userId, bankId);
    }

    /**
     * 创建考试记录
     */
    public Record createExamRecord(Long userId, Integer bankId) {
        Record record = new Record();
        record.set("user_id", userId);
        record.set("bank_id", bankId);
        record.set("create_time", new Date());
        record.set("seconds", null);
        record.set("score", null);

        Db.save("lims_exam_record", record);
        return record;
    }

    /**
     * 获取考试详情
     */
    public Record getExamDetail(Integer recordId) {
        String sql = "SELECT er.* FROM lims_exam_record er " +
                "WHERE er.id = ?";

        return Db.findFirst(sql, recordId);
    }

    /**
     * 更新考试结果
     */
    public boolean updateExamResult(Integer recordId, Double score, Integer seconds, String result) {
        Record record = new Record();
        record.set("id", recordId);
        record.set("score", score);
        record.set("seconds", seconds);
        record.set("result", result);
        record.set("update_time", new Date());

        return Db.update("lims_exam_record", record);
    }






    /**
     * 解析ext_json字段
     */
    public void parseExtJsonData(Record record) {
        String extJson = record.getStr("ext_json");
        if (extJson != null && !extJson.isEmpty()) {
            try {
                // 解析ext_json为GeneratePaperRequest对象
                GeneratePaperRequest request = JSON.parseObject(extJson, GeneratePaperRequest.class);

                // 提取题目数量
                if (request.getQuestionCount() != null) {
                    record.set("question_count", request.getQuestionCount());
                }

                // 提取题型并转换为汉字
                if (request.getQuestionType() != null) {
                    record.set("question_type", request.getQuestionType());
                    record.set("question_type_text", getQuestionTypeText(request.getQuestionType()));
                }

                // 提取知识点名称并用逗号分隔
                if (request.getKnowledgeConfig() != null && !request.getKnowledgeConfig().isEmpty()) {
                    List<String> knowledgeNames = new ArrayList<>();
                    for (KnowledgeConfig knowledge : request.getKnowledgeConfig()) {
                        if (knowledge.getName() != null) {
                            knowledgeNames.add(knowledge.getName());
                        }
                    }
                    record.set("knowledge_names", String.join("，", knowledgeNames));

                    // 如果需要显示权重信息
                    StringBuilder knowledgeWithWeight = new StringBuilder();
                    for (int i = 0; i < request.getKnowledgeConfig().size(); i++) {
                        KnowledgeConfig knowledge = request.getKnowledgeConfig().get(i);
                        if (i > 0) knowledgeWithWeight.append("，");
                        knowledgeWithWeight.append(knowledge.getName());
                        if (knowledge.getWeight() != null) {
                            knowledgeWithWeight.append("(").append(knowledge.getWeight()).append("%)");
                        }
                    }
                    record.set("knowledge_with_weight", knowledgeWithWeight.toString());
                }

                // 提取总权重
                if (request.getTotalWeight() != null) {
                    record.set("total_weight", request.getTotalWeight());
                }

            } catch (Exception e) {
                System.err.println("解析ext_json失败: " + e.getMessage());
                setDefaultValues(record);
            }
        } else {
            setDefaultValues(record);
        }
    }

    /**
     * 获取题型对应的汉字
     */
    private String getQuestionTypeText(String questionType) {
        if (questionType == null) return "未知题型";

        switch (questionType) {
            case "single":
                return "单选题";
            case "multiple":
                return "多选题";
            case "judge":
                return "判断题";
            case "essay":
                return "问答题";
            default:
                return questionType;
        }
    }

    /**
     * 设置默认值
     */
    private void setDefaultValues(Record record) {
        record.set("question_count", 0);
        record.set("question_type_text", "未知题型");
        record.set("knowledge_names", "未知知识点");
    }
}


